package com.liujit.pay.wx.kit;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.liujit.pay.wx.domain.result.RefundsResult;
import com.liujit.pay.wx.domain.result.refunds.RefundsAmount;
import com.liujit.pay.wx.domain.result.refunds.RefundsGoodsDetail;
import com.liujit.pay.wx.domain.result.refunds.RefundsPromotionDetail;
import com.liujit.pay.wx.enums.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 订单查询工具类
 * @author: liujun
 * @create: 2021-02-22 16:08
 */
public class RefundsKit {

    /**
     * 获取请求参数
     *
     * @return
     */
    public static RefundsResult getResult(JSONObject respJson) {
        RefundsResult result = new RefundsResult();
        // 微信支付退款号
        result.setRefundId(respJson.getStr("refund_id"));
        // 商户退款单号
        result.setOutRefundNo(respJson.getStr("out_refund_no"));
        // 微信支付订单号
        result.setTransactionId(respJson.getStr("transaction_id"));
        // 商户订单号
        result.setOutTradeNo(respJson.getStr("out_trade_no"));
        // 退款渠道
        result.setChannel(respJson.getStr("channel"));
        result.setChannelName(RefundsChannel.getName(result.getChannel()));
        // 退款入账账户
        result.setUserReceivedAccount(respJson.getStr("user_received_account"));
        // 退款成功时间
        String successTime = respJson.getStr("success_time");
        if (StrUtil.isNotBlank(successTime)) {
            result.setSuccessTime(successTime);
        }
        // 退款创建时间
        result.setCreateTime(respJson.getStr("create_time"));
        // 退款状态
        result.setStatus(respJson.getStr("status"));
        result.setStatusName(RefundsStatus.getName(result.getStatus()));
        // 资金账户
        String fundsAccount = respJson.getStr("funds_account");
        if (StrUtil.isNotBlank(fundsAccount)) {
            result.setFundsAccount(fundsAccount);
            result.setFundsAccountName(RefundsFundsAccount.getName(result.getFundsAccount()));
        }
        // 金额信息
        result.setRefundsAmount(getAmount(respJson.getJSONObject("amount")));
        // 优惠退款信息
        JSONArray promotionDetailArray = respJson.getJSONArray("promotion_detail");
        if (promotionDetailArray != null) {
            result.setRefundsPromotionDetailList(getPromotionDetailList(promotionDetailArray));
        }
        return result;
    }

    /**
     * 获取金额信息
     *
     * @param amount
     * @return
     */
    private static RefundsAmount getAmount(JSONObject amount) {
        RefundsAmount result = new RefundsAmount();
        // 订单金额
        result.setTotal(amount.getInt("total"));
        // 退款金额
        result.setRefund(amount.getInt("refund"));
        // 用户支付金额
        result.setPayerTotal(amount.getInt("payer_total"));
        // 用户退款金额
        result.setPayerRefund(amount.getInt("payer_refund"));
        // 应结退款金额
        result.setSettlementRefund(amount.getInt("settlement_refund"));
        // 应结订单金额
        result.setSettlementTotal(amount.getInt("settlement_total"));
        // 优惠退款金额
        result.setDiscountRefund(amount.getInt("discount_refund"));
        // 退款币种
        result.setCurrency(amount.getStr("currency"));
        return result;
    }

    /**
     * 获取优惠退款信息
     *
     * @param promotionDetailArray
     * @return
     */
    private static List<RefundsPromotionDetail> getPromotionDetailList(JSONArray promotionDetailArray) {
        List<RefundsPromotionDetail> result = new ArrayList<>();
        for (int i = 0; i < promotionDetailArray.size(); i++) {
            JSONObject promotionDetail = promotionDetailArray.getJSONObject(i);
            RefundsPromotionDetail refundsPromotionDetail = new RefundsPromotionDetail();
            // 券ID
            refundsPromotionDetail.setPromotionId(promotionDetail.getStr("promotion_id"));
            // 优惠范围
            refundsPromotionDetail.setScope(promotionDetail.getStr("scope"));
            refundsPromotionDetail.setScopeName(PromotionScope.getName(refundsPromotionDetail.getScope()));
            // 优惠类型
            refundsPromotionDetail.setType(promotionDetail.getStr("type"));
            refundsPromotionDetail.setTypeName(PromotionType.getName(refundsPromotionDetail.getType()));
            // 优惠券面额
            refundsPromotionDetail.setAmount(promotionDetail.getInt("amount"));
            // 优惠退款金额
            refundsPromotionDetail.setRefundAmount(promotionDetail.getInt("refund_amount"));
            // 商品列表
            JSONArray goodsDetailArray = promotionDetail.getJSONArray("goods_detail");
            if (goodsDetailArray != null) {
                List<RefundsGoodsDetail> refundsGoodsDetailList = new ArrayList<>();
                for (int j = 0; j < goodsDetailArray.size(); j++) {
                    JSONObject goodsDetail = goodsDetailArray.getJSONObject(j);
                    RefundsGoodsDetail refundsGoodsDetail = new RefundsGoodsDetail();
                    // 商户侧商品编码
                    refundsGoodsDetail.setMerchantGoodsId(goodsDetail.getStr("merchant_goods_id"));
                    // 微信侧商品编码
                    String wechatPayGoodsId = goodsDetail.getStr("wechatpay_goods_id");
                    if (StrUtil.isNotBlank(wechatPayGoodsId)) {
                        refundsGoodsDetail.setWechatPayGoodsId(wechatPayGoodsId);
                    }
                    // 商品名称
                    String goodsName = goodsDetail.getStr("goods_name");
                    if (StrUtil.isNotBlank(goodsName)) {
                        refundsGoodsDetail.setGoodsName(goodsName);
                    }
                    // 商品单价
                    refundsGoodsDetail.setUnitPrice(goodsDetail.getInt("unit_price"));
                    // 商品退款金额
                    refundsGoodsDetail.setRefundAmount(goodsDetail.getInt("refund_amount"));
                    // 商品退货数量
                    refundsGoodsDetail.setRefundQuantity(goodsDetail.getInt("refund_quantity"));
                    refundsGoodsDetailList.add(refundsGoodsDetail);
                }
                refundsPromotionDetail.setRefundsGoodsDetailList(refundsGoodsDetailList);
            }
            result.add(refundsPromotionDetail);
        }
        return result;
    }
}
